//! 日期时间生成器模块

use chrono::{DateTime, Duration, NaiveDate, Utc, Datelike};
use rand::Rng;

/// 生成指定范围内的随机日期时间
pub fn datetime_range(start: DateTime<Utc>, end: DateTime<Utc>) -> DateTime<Utc> {
    let mut rng = rand::thread_rng();
    let secs = end.timestamp() - start.timestamp();
    let random_secs = rng.gen_range(0..secs);
    start + Duration::seconds(random_secs)
}

/// 生成过去N天内的随机日期时间
pub fn datetime_past_days(days: i64) -> DateTime<Utc> {
    let now = Utc::now();
    let past = now - Duration::days(days);
    datetime_range(past, now)
}

/// 生成未来N天内的随机日期时间
pub fn datetime_future_days(days: i64) -> DateTime<Utc> {
    let now = Utc::now();
    let future = now + Duration::days(days);
    datetime_range(now, future)
}

/// 生成今年内的随机日期
pub fn datetime_this_year() -> DateTime<Utc> {
    let now = Utc::now();
    let year = now.year();
    let start = NaiveDate::from_ymd_opt(year, 1, 1)
        .unwrap()
        .and_hms_opt(0, 0, 0)
        .unwrap()
        .and_utc();
    let end = NaiveDate::from_ymd_opt(year, 12, 31)
        .unwrap()
        .and_hms_opt(23, 59, 59)
        .unwrap()
        .and_utc();
    datetime_range(start, end)
}

/// 生成生日日期（18-80岁之间）
pub fn birthday() -> DateTime<Utc> {
    let now = Utc::now();
    let min_age = 18;
    let max_age = 80;
    
    let mut rng = rand::thread_rng();
    let age = rng.gen_range(min_age..=max_age);
    
    let birth_year = now.year() - age;
    let birth_month = rng.gen_range(1..=12);
    let birth_day = rng.gen_range(1..=28); // 简化处理，避免月份天数问题
    
    NaiveDate::from_ymd_opt(birth_year, birth_month, birth_day)
        .unwrap()
        .and_hms_opt(rng.gen_range(0..24), rng.gen_range(0..60), rng.gen_range(0..60))
        .unwrap()
        .and_utc()
}

/// 生成工作时间（9:00-18:00）
pub fn work_time() -> String {
    let mut rng = rand::thread_rng();
    let hour = rng.gen_range(9..18);
    let minute = rng.gen_range(0..60);
    format!("{:02}:{:02}", hour, minute)
}

/// 生成时间戳
pub fn timestamp() -> i64 {
    Utc::now().timestamp()
}

/// 生成ISO 8601格式的日期时间字符串
pub fn iso8601() -> String {
    Utc::now().to_rfc3339()
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_datetime_past_days() {
        let dt = datetime_past_days(30);
        let now = Utc::now();
        assert!(dt < now);
        assert!(dt > now - Duration::days(30));
    }

    #[test]
    fn test_birthday() {
        let birth = birthday();
        let now = Utc::now();
        let age = now.year() - birth.year();
        assert!(age >= 18 && age <= 80);
    }

    #[test]
    fn test_work_time() {
        let time = work_time();
        assert!(time.contains(':'));
        let parts: Vec<&str> = time.split(':').collect();
        assert_eq!(parts.len(), 2);
        
        let hour: u32 = parts[0].parse().unwrap();
        assert!(hour >= 9 && hour < 18);
    }
}